package tunnel;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;

import java.io.IOException;

/**
 * 小象代理隧道代理示例 - JAVA，类库 httpclient
 *
 * @author xxdl
 */
public class HttpClient45Demo {
    // 应用账号（请替换为真实账号）
    private static String appKey = "appKey";
    // 应用密码（请替换为真实密码）
    private static String appSecret = "appSecret";

    // 代理服务器
    private final static String ProxyHost = "http-dynamic.xiaoxiangdaili.com";
    private final static Integer ProxyPort = 10030;

    private static HttpHost proxy = null;
    private static HttpClientBuilder clientBuilder = null;

    static {
        proxy = new HttpHost(ProxyHost, ProxyPort, "http");

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(appKey, appSecret));

        SocketConfig socketConfig = SocketConfig.custom().setSoTimeout(3000).build();

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(3000)
                .setConnectTimeout(3000)
                .setSocketTimeout(3000)
                .setExpectContinueEnabled(false)
                .setProxy(proxy)
                .build();

        clientBuilder = HttpClients.custom()
                .setDefaultSocketConfig(socketConfig)
                .disableAutomaticRetries()
                .setDefaultRequestConfig(requestConfig)
                .setDefaultCredentialsProvider(credsProvider);
    }

    private static void getUrlContent(String url) {
        HttpGet httpGet = new HttpGet(url);
        httpGet.addHeader("Accept-Encoding", "gzip"); // 使用gzip压缩传输数据让访问更快
        httpGet.addHeader("Connection", "close");

        CloseableHttpResponse httpResp = null;

        try {
            // JDK 8u111版本后，目标页面为HTTPS协议，启用proxy用户密码鉴权
            System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");

            AuthCache authCache = new BasicAuthCache();
            authCache.put(proxy, new BasicScheme());

            HttpClientContext localContext = HttpClientContext.create();
            localContext.setAuthCache(authCache);

            httpResp = clientBuilder.build().execute(httpGet, localContext);

            String html = IOUtils.toString(httpResp.getEntity().getContent(), "GB2312");
            System.out.println(html);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpResp != null) {
                    httpResp.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception {
        // 要访问的目标页面
        String targetUrl = "http://httpbin.org/ip";
        getUrlContent(targetUrl);
    }
}
